#ifndef MAP_H
#define MAP_H

#include <vector>
#include <string>

/**
 * @brief 地图类，用于存储和处理游戏地图文件及显示地图状态
 * 支持从txt文件中加载的地图数据，支持两种格式：
 * 1. 字符格式：空格表示可移动区域，"-"和"|"表示墙壁，"#"表示交互元素
 * 2. 数字格式：0表示可移动区域，1表示墙壁，2-9表示不同类型的交互元素
 */
class Map {
public:
    /**
     * @brief 地图元素类型枚举
     */
    enum class CellType {
        EMPTY = 0,      // 可移动区域
        WALL = 1,       // 墙壁
        INTERACTIVE = 2 // 交互元素
    };

    /**
     * @brief 方向枚举
     */
    enum class Direction {
        UP,
        DOWN,
        LEFT,
        RIGHT
    };

    /**
     * @brief 构造函数
     */
    Map();

    /**
     * @brief 析构函数
     */
    ~Map();

    /**
     * @brief 加载指定章节的地图
     * @param chapterNumber 章节编号（1-18）
     * @return 加载成功返回true，失败返回false
     */
    bool loadMapFromFile(int chapterNumber);

    /**
     * @brief 在控制台显示当前地图（包含角色位置）
     */
    void displayMap() const;

    /**
     * @brief 获取指定位置的地图元素类型
     * @param row 行坐标
     * @param col 列坐标
     * @return 该位置的元素类型
     */
    CellType getCellType(int row, int col) const;

    /**
     * @brief 检查指定位置是否可移动
     * @param row 行坐标
     * @param col 列坐标
     * @return 可移动返回true，否则返回false
     */
    bool isMovable(int row, int col) const;

    /**
     * @brief 检查指定位置是否为交互元素
     * @param row 行坐标
     * @param col 列坐标
     * @return 是交互元素返回true，否则返回false
     */
    bool isInteractive(int row, int col) const;

    /**
     * @brief 获取地图高度
     * @return 地图行数
     */
    int getHeight() const;

    /**
     * @brief 获取地图宽度
     * @return 地图列数
     */
    int getWidth() const;

    /**
     * @brief 获取交互元素的具体类型
     * @param row 行坐标
     * @param col 列坐标
     * @return 交互元素类型（2-9），不是交互元素返回0
     */
    int getInteractiveType(int row, int col) const;

    /**
     * @brief 清空当前地图数据
     */
    void clearMap();

    /**
     * @brief 检查地图是否已加载
     * @return 已加载返回true，否则返回false
     */
    bool isMapLoaded() const;

    /**
     * @brief 设置角色初始位置
     * @param row 行坐标
     * @param col 列坐标
     * @return 设置成功返回true（位置合法），否则返回false
     */
    bool setPlayerPosition(int row, int col);

    /**
     * @brief 移动角色
     * @param dir 移动方向
     * @return 移动成功返回true，否则返回false
     */
    bool movePlayer(Direction dir);

    /**
     * @brief 获取当前角色位置
     * @param[out] row 行坐标
     * @param[out] col 列坐标
     */
    void getPlayerPosition(int& row, int& col) const;

    /**
     * @brief 解锁指定区域
     * @param areaId 要解锁的区域ID
     * @return 解锁成功返回true，否则返回false
     */
    bool unlockArea(int areaId);

    /**
     * @brief 检查当前位置是否触发事件
     * @return 事件ID，0表示未触发任何事件
     */
    int checkEventTrigger() const;

private:
    std::vector<std::vector<int>> mapData_; // 地图数据存储
    std::vector<bool> unlockedAreas_; // 已解锁区域列表
    int mapWidth_; // 地图宽度
    int mapHeight_; // 地图高度
    bool isLoaded_; // 地图加载状态标识
    int currentChapter_; // 当前章节编号
    int playerRow_; // 角色当前行坐标
    int playerCol_; // 角色当前列坐标

    /**
     * @brief 加载字符格式的地图文件
     * @param fileName 文件名
     * @return 加载成功返回true，失败返回false
     */
    bool loadCharacterMap(const std::string& fileName);

    /**
     * @brief 加载数字格式的地图文件
     * @param fileName 文件名
     * @return 加载成功返回true，失败返回false
     */
    bool loadDataMap(const std::string& fileName);

    /**
     * @brief 将字符转换为对应的地图元素类型
     * @param ch 输入字符
     * @return 对应的元素类型值
     */
    int charToMapType(char ch) const;

    /**
     * @brief 检查坐标是否在地图范围内
     * @param row 行坐标
     * @param col 列坐标
     * @return 在范围内返回true，否则返回false
     */
    bool isValidPosition(int row, int col) const;

    /**
     * @brief 应用区域解锁到地图数据
     * @param areaId 已解锁的区域ID
     */
    void applyAreaUnlock(int areaId);
};

#endif // MAP_H
